import { ObjType } from '@/@type/index'
import config from '@/config'
import { deep, getRandom } from '@/utils/index'
import * as auth from '@/utils/auth'
import { handleLogout } from './auth'
import { hideLoading, loading, toast } from './message'
import { cosUploadFile, getCosName } from '@/utils/cos/cosUpload'
type UploadType = {
  filePath?: any
  url?: string
  fileType?: 'image' | 'video' | 'audio'
  name?: string //文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容
  header?: ObjType // 请求头
  formData?: ObjType // 请求头
  timeout?: number // 超时时间
  ossFileName?: string //oss 文件名
}

let loadingStack: any[] = []

export const handleUpload = async (
  uploadParam: UploadType,
  type: 'oss' | 'common' | 'cos' = 'cos'
) => {
  const query = deep({
    filePath: uploadParam.filePath,
    url: uploadParam.url || '',
    fileType: uploadParam.fileType || 'image',
    name: uploadParam.name || 'images',
    header: uploadParam.header || {},
    formData: uploadParam.formData || {},
    timeout: uploadParam.timeout || 10000,
    ossFileName: uploadParam.ossFileName
  })

  let reqQuery = {} as any
  if (type === 'common') {
    reqQuery = commonUpload(query)
  } else if (type === 'oss') {
    reqQuery = await ossUpload(query)
  }
  const loadingKey = getRandom()
  if (!loadingStack.length) {
    loading('数据处理中..')
  }
  loadingStack.push(loadingKey)
  return new Promise((resolve, reject) => {
    if (type === 'cos') {
      let key = undefined as any
      if (query.ossFileName) {
        key = getCosName(query.ossFileName)
      }
      cosUploadFile({ filePath: uploadParam.filePath, key })
        .then((res) => {
          filterLoading(loadingKey)
          resolve({ url: res })
        })
        .catch(() => {
          handleUploadError()
        })
      return
    }
    uni.uploadFile({
      ...reqQuery,
      success: (res) => {
        const resData = {
          url: type === 'oss' ? reqQuery.ossFileUrl : 'common'
        }
        if (type === 'common') {
          const data = JSON.parse(res.data)
          if (data.code === 0) {
            resData.url = data.data
          } else {
            handleUploadError(data.message)
            if (data.code === 1000) {
              handleLogout()
            }
            reject(data)
            return
          }
        }

        filterLoading(loadingKey)
        resolve(resData)
      },
      fail: (err) => {
        handleUploadError()
        console.log(err, '上传失败')
        reject(err)
      }
    })
  }) as Promise<{ url: string }>
}

function handleUploadError(msg = '数据处理错误') {
  toast(msg)
  loadingStack = []
  hideLoading()
}

function filterLoading(loadingKey) {
  loadingStack = loadingStack.filter((i) => i !== loadingKey)
  console.log(loadingStack, loadingKey)
  if (loadingStack.length === 0) {
    hideLoading()
  }
}

export const ossUpload = (query) => {
  return uni.$api.oss(query.formData).then(async (res) => {
    query.url = res.host
    query.name = 'file'
    let resKey = res.key + getRandom()
    if (query.ossFileName) {
      resKey = resKey + query.ossFileName
    }
    query.formData.key = resKey
    query.formData.OSSAccessKeyId = res.OSSAccessKeyId
    query.formData.policy = res.policy
    query.formData.signature = res.signature
    query.formData['x-oss-object-acl'] = res['x-oss-object-acl']
    query.formData['success_action_status'] = res['success_action_status']
    query.formData.expire = res.expire
    query.ossFileUrl = `${res.host}/${resKey}`
    return query
  })
}

export const commonUpload = (query) => {
  //
  query.url = config.host + '/images/upload'
  const token = auth.getLocToken()
  query.header = {
    Authorization: `Bearer ${token}`
  }

  return query
}
